package com.surrey.p2p.view;

import java.awt.Color;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;

import com.surrey.p2p.model.CANNode;
import com.surrey.p2p.model.P2PNode;

import edu.uci.ics.jung.algorithms.layout.StaticLayout;
import edu.uci.ics.jung.graph.DirectedSparseGraph;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;

public class P2PNetworkRenderer {

	Graph<CANNode, String> g;
	VisualizationViewer<CANNode, String> vv;
	private ArrayList<String> coloured;
	private ArrayList<P2PNode> busy;
	private ArrayList<P2PNode> destinationNode;

	public P2PNetworkRenderer() {
		g = new DirectedSparseGraph<CANNode, String>();
		coloured = new ArrayList<String>();
		busy = new ArrayList<P2PNode>();
		destinationNode = new ArrayList<P2PNode>();
	}

	public void drawGraph() {
		
		StaticLayout<CANNode, String> layout = new StaticLayout<CANNode, String>(g, new LocationTransformer());
		layout.setSize(new Dimension(600, 600));
		vv = new VisualizationViewer<CANNode, String>(layout);
		vv.setPreferredSize(new Dimension(600, 600));
		vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller<CANNode>());
		vv.setBackground(Color.WHITE);
		vv.getRenderContext().setVertexFillPaintTransformer(new VertexColourTransformer(busy, destinationNode));
		vv.getRenderContext().setEdgeDrawPaintTransformer(new EdgeColourTransformer(this.coloured));
		vv.getRenderContext().setArrowFillPaintTransformer(new EdgeColourTransformer(this.coloured));
		vv.getRenderContext().setArrowDrawPaintTransformer(new EdgeColourTransformer(this.coloured));
		JFrame frame = new JFrame("P2P Graph");

		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().add(vv);
		vv.setOpaque(false);

		frame.pack();
		frame.setVisible(true);
	}

	public void addNodeToVisualisation(CANNode c) {
		g.addVertex(c);
		List<CANNode> neighbours = c.getNeighbours();
		if(neighbours!=null)
		for (CANNode n : neighbours) {
			g.addEdge((c.getAddress().getIpAddress() + n.getAddress().getIpAddress()), c, n);
		}
		vv.repaint();
	}

	public void displayRouting(String edge, P2PNode a) {
		coloured.add(edge);
		if (!busy.contains(a)) {
			busy.add(a);
		}
		long currentTime = System.currentTimeMillis();
		long intended = currentTime + 500;
		while (currentTime < intended) {
			currentTime = System.currentTimeMillis();
		}
		vv.repaint();
	}

	public void finishRouting(P2PNode node) {
		long currentTime = System.currentTimeMillis();
		long intended = currentTime + 1000;
		destinationNode.add(node);
		vv.repaint();
		while (currentTime < intended) {
			currentTime = System.currentTimeMillis();
		}
		destinationNode.clear();
		coloured.clear();
		busy.clear();
		vv.repaint();
	}

	public void takeNodeOffline(CANNode c) {
		vv.repaint();
	}

}
